home *** CD-ROM | disk | FTP | other *** search
- /* ================================================================== *
- * Editor mined *
- * Part 1 *
- * for documentation see mined.doc *
- * ================================================================== */
-
- #include "mined.h"
-
- /* #define DEBUG */
-
- /* ================================================================== *
- * Definitions specific for mined1.c *
- * ================================================================== */
-
- #ifndef helpcommand
-
- # ifdef unix
- # define helpcommand "man mined"
- # endif
-
- # ifdef vms
- # define helpcommand "help mined"
- # endif
-
- # ifdef msdos
- # define helpcommand "more < %smined.hlp"
- # endif
-
- #endif
-
- #ifndef printcommand
-
- # ifdef unix
- # ifdef sysV
- # define printcommand "lp %s"
- # else
- # define printcommand "lpr %s"
- # endif
- # endif
-
- # ifdef vms
- # define printcommand "print %s"
- # endif
-
- # ifdef msdos
- # define printcommand "copy %s prn: > nul:"
- # endif
-
- #endif
-
- /* ================================================================== *
- * Data section *
- * ================================================================== */
-
- LINE * header; /* Head of line list */
- LINE * tail; /* Last line in line list */
- LINE * cur_line; /* Current line in use */
- LINE * top_line; /* First line of screen */
- LINE * bot_line; /* Last line of screen */
- char * cur_text; /* Current char on current line in use */
- int last_y; /* Last y of screen. Usually SCREENMAX */
- int x = 0, y = 0; /* x, y coordinates on screen */
-
- short YMAX, XMAX;
- char screen [screen_BUFL + 1]; /* I/O buffer for "writes" and "reads" */
- int total_lines = 0; /* Number of lines in file */
- long total_chars = -1L; /* Number of characters in file */
- FLAG modified = FALSE; /* Set when file is modified */
- FLAG viewonly = FALSE; /* Set when view only mode is selected */
- FLAG overwriteOK = FALSE; /* Set if current file is OK for overwrite */
- FLAG writable; /* Set if file cannot be written */
- FLAG loading = TRUE; /* Loading a file? Init TRUE for error handling */
- FLAG quit = FALSE; /* Set when quit character is typed */
- FLAG intr_char = FALSE; /* Set when intr character is typed */
- FLAG winchg = FALSE; /* Set when window size has changed */
- FLAG isscreenmode = FALSE; /* Set when screen mode is on */
- FLAG stat_visible; /* Set if status_line is visible */
- FLAG fstat_always = FALSE; /* Permanent file status display wanted ? */
- FLAG waitingforinput = FALSE; /* Set while waiting for the next command key */
- FLAG rpipe = FALSE; /* Set if file should be read from stdin */
- FLAG wpipe = FALSE; /* Set if file should be written to stdout */
- FLAG multiexit = TRUE; /* Should exit command go to next file? */
- FLAG proportional = FALSE; /* Enable support for proportional fonts? */
- FLAG controlQS = FALSE; /* must respect ^Q/^S handshake ? */
- FLAG insert_mode = TRUE; /* insert or overwrite */
- uchar control_prefix = '\026'; /* ^V/^P character to prefix control chars */
- FLAG Chinese = FALSE; /* set if two-byte characters are enabled */
- FLAG page_scroll = FALSE; /* use scroll for page up/down */
- FLAG page_stay = FALSE; /* stay at edge of screen after page up/down */
- #ifdef pc
- int display_delay = 9; /* delay between display lines */
- #else
- int display_delay = -1; /* Unix terminals are slow enough anyway */
- #endif
- #ifdef msdos
- char RET_opt = 'r'; /* handle RET chars: ignore / newline */
- #else
- char RET_opt = ' '; /* handle RET chars: ignore / newline */
- #endif
- long chars_saved; /* Nr of chars in buffer */
- int input_fd = STD_IN; /* File descriptors for terminal dialog */
- int output_fd = STD_ERR;
- int out_count = 0; /* Index in output buffer */
- char file_name [maxLINE_LEN]; /* Name of file in use */
- char text_buffer [MAX_CHARS]; /* for get_line, modifications, build_string */
- int hop_flag = 0; /* Counter for the HOP function */
- char TABchar = ' '; /* Char to be shown in place of tab chars */
- char SHIFT_BEG = '\0'; /* Char indicating that line continues left */
- char RET_MARK = '\0'; /* Char indicating end of line */
- char RET_BLANK = '\0'; /* Char to fill the end of line with */
- char RET_BLANK2 = '\0'; /* Char to fill last position of line with */
- #ifdef vms
- int fprot = 0; /* To be used for file creatings */
- int bufprot = 0; /* To be used for paste buffer file */
- #else
- int fprot = 0644; /* To be used for file creatings */
- int bufprot = 0600; /* To be used for paste buffer file */
- #endif
- int fnami; /* Parameter index of current file name */
- int fnami_min, fnami_max, fnami_cnt;
- /* char * (* fnamv) []; */
- char * * fnamv; /* Copy of argv. Points to program params */
-
- int left_margin = 0;
- int right_margin = 71;
-
- /*
- * Yank variables.
- */
- char * temp_dir;
- char yank_file [maxLINE_LEN];
- char yankie_file [maxLINE_LEN];
- char panic_file [maxLINE_LEN];
- char mined_dir [maxLINE_LEN]; /* startup directory to locate help file */
-
- /* ================================================================== *
- * Text buffer routines *
- * ================================================================== */
-
- int old_x = 0; /* previous x position */
-
- /*
- * Find_x () returns the x coordinate belonging to address.
- * (Tabs are expanded).
- */
- int
- find_x (line, address)
- LINE * line;
- char * address;
- {
- register char * textp = line->text;
- register int x_left = get_shift (line->shift_count) * - SHIFT_SIZE;
- register int x_in_line = 0; /* must start from 0 to calculate correct
- tab positions (since SHIFT_SIZE is not guaranteed
- to be a multiple of 8) */
- /* Alright, SHIFT_SIZE is now guaranteed to be a multiple of 8
- due to lots of display problems related to that matter.
- Leave this code anyway. */
-
- while (textp != address && * textp != '\0') {
- if (is_tab (* textp ++)) /* Expand tabs */
- x_in_line = tab (x_in_line);
- else
- x_in_line ++;
- }
- return x_in_line + x_left;
- }
-
- /*
- * Find_address () returns the pointer in the line with given offset.
- * (Tabs are expanded).
- * find_address is only called by move_it ()
- get_shift (cnt) is ((cnt) & DUMMY_MASK) ; DUMMY_MASK is 0x7F
- tab (cnt) is (((cnt) + 8) & ~07)
- is_tab (c) is ((c) == '\t')
- */
- char *
- find_address (line, new_x, cur_x)
- LINE * line;
- int new_x;
- int * cur_x;
- {
- register char * textp = line->text;
- register int tx = get_shift (line->shift_count) * - SHIFT_SIZE;
-
- while (tx < new_x && * textp != '\n') {
- if (is_tab (* textp)) {
- if (new_x == old_x /* (* cur_x) */ - 1 && tab (tx) > new_x)
- break; /* Moving left over tab */
- else
- tx = tab (tx);
- }
- else tx ++;
- textp ++;
- }
- * cur_x = tx;
- return textp;
- }
-
- /*
- * inmultichar (string, charpoi) determines if charpoi points to the second
- * byte of a multi-byte character within string
- */
- int
- inmultichar (string, charpoi)
- uchar * string;
- uchar * charpoi;
- {
- while (string < charpoi) {
- if (multichar (* string)) {
- string ++;
- if (* string != '\n' /* would be an error */) string ++;
- } else
- string ++;
- }
- return string > charpoi;
- }
-
- /*
- * move_to: move to given coordinates on screen.
- * move_y: move to given line on screen, staying in last explicit column.
- * move_address: move to given line at given text position.
- * The caller must check that scrolling is not needed.
- * If new x-position is < 0 or > XBREAK, move_it () will check if
- * the line can be shifted. If it can it sets (or resets) the shift_count
- * field of the current line accordingly. By this mechanism, the
- * pseudo-x-positions LINE_START / LINE_END (a very small / big value)
- * perform the appropriate positioning actions.
- * Move also sets cur_text to the right char.
- * "If we're moving to the same x coordinate, try to move the the x-coordinate
- * used on the other previous call." -- This worked erroneously and was
- * replaced by an explicit old_x variable and move_y call.
- * move_address is directly called by move_next/previous_word(), re_search(), RDwin()
- */
- void
- move_it (new_x, new_address, new_y)
- register int new_x;
- int new_y;
- char * new_address;
- {
- register LINE * line = cur_line; /* For building new cur_line */
- int shift = 0; /* How many shifts to make */
- /* static int rel_x = 0; */ /* Remember relative x position */
- /* This was used as a trick to stay virtually in the previous column
- even when moving across shorter lines; but it had >= 2 errors.
- Renamed to old_x, made globally accessible and explicitly used
- by appropriate calls to avoid these problems. TW */
- int tx = x;
-
- /* Check for illegal values */
- if (new_y < 0 || new_y > last_y)
- return;
-
- /* Adjust y-coordinate and cur_line */
- if (new_y < y)
- while (y != new_y) {
- y --;
- line = line->prev;
- }
- else
- while (y != new_y) {
- y ++;
- line = line->next;
- }
-
- /* Set or unset relative x-coordinate */
- if (new_address == NIL_PTR) {
- new_address = find_address (line, new_x, & tx);
- new_x = tx;
- }
- else
- /* rel_x = */ new_x = find_x (line, new_address);
-
- /* Adjust on character boundary */
- if (Chinese == TRUE) {
- if (inmultichar (line->text, new_address)) {
- /* adjust position which is currently within a multi-byte character */
- if (new_x >= x) {
- new_x ++;
- new_address ++;
- } else {
- new_x --;
- new_address --;
- }
- }
- }
-
- /* Adjust shift_count if new_x lower than 0 or higher than XBREAK */
- /* Allow adjustment also if new_x == 0 to enable left shift mark */
- if (new_x <= 0 || new_x >= XBREAK) {
- if (new_x > XBREAK || (new_x == XBREAK && * new_address != '\n'))
- shift = (new_x - XBREAK) / SHIFT_SIZE + 1;
- else {
- shift = new_x / SHIFT_SIZE;
- if (new_x % SHIFT_SIZE)
- shift --;
- if (new_x == 0 && line->shift_count != 0 && SHIFT_BEG != '\0')
- shift --;
- }
-
- if (shift != 0) {
- line->shift_count += shift;
- new_x = find_x (line, new_address);
- if (new_x == 0 && line->shift_count != 0 && SHIFT_BEG != '\0')
- { line->shift_count --;
- new_x = find_x (line, new_address);
- }
- set_cursor (0, y);
- line_print (line);
- /* rel_x = new_x; */
- }
- }
-
- /* Assign and position cursor */
- x = new_x;
- cur_text = new_address;
- cur_line = line;
- set_cursor_xy ();
- }
-
- void
- move_y (ny)
- register int ny;
- {
- move_it (old_x, NIL_PTR, ny);
- }
-
- void
- move_to (nx, ny)
- register int nx;
- register int ny;
- {
- old_x = x;
- move_it (nx, NIL_PTR, ny);
- old_x = x;
- }
-
- void
- move_address (nadd, ny)
- register char * nadd;
- register int ny;
- {
- old_x = x;
- move_it (0, nadd, ny);
- old_x = x;
- }
-
- /*
- * Initialize is called when a another file is edited. It free's the allocated
- * space and sets modified back to FALSE and fixes the header/tail pointer.
- */
- void
- initialize ()
- {
- register LINE * line, * next_line;
-
- /* Delete the whole list */
- for (line = header->next; line != tail; line = next_line) {
- next_line = line->next;
- free_space (line->text);
- free_header (line);
- }
-
- /* header and tail should point to itself */
- line->next = line->prev = line;
- x = y = 0;
- rpipe = modified = FALSE;
- }
-
- /*
- * Get_line reads one line from filedescriptor fd. If EOF is reached on fd,
- * get_line () returns ERRORS, else it returns the length of the string.
- */
- char * get_l_err1;
- char * get_l_err2;
- char last_char = '\0';
-
- int
- get_line (fd, buffer)
- int fd;
- register char buffer [MAX_CHARS];
- {
- static char * last = NIL_PTR;
- static char * current = NIL_PTR;
- static int read_chars;
- register char * cur_pos = current;
- char * begin = buffer;
- char * fini = buffer + MAX_CHARS - 2 /* leave space for '\n\0' */;
- register FLAG ignore1char;
-
- do {
- do {
- ignore1char = FALSE;
- if (cur_pos == last) {
- if ((read_chars = read (fd, screen, screen_BUFL)) <= 0)
- break;
- last = & screen [read_chars];
- cur_pos = screen;
- }
-
- if (* cur_pos == '\0' ) {
- get_l_err1 = "File contains NULL char's - changed to DEL's - ";
- * cur_pos = '\177';
- }
-
- #ifdef msdos
- if (* cur_pos == '\n' && last_char != '\r')
- modified = TRUE;
- #endif
- if (RET_opt == 'R' && * cur_pos == '\n' && last_char == '\r') {
- last_char = * cur_pos;
- cur_pos ++;
- ignore1char = TRUE;
- modified = TRUE;
- }
- else
- last_char = * cur_pos;
-
- if (* cur_pos == '\r' ) {
- if (RET_opt == 'R') {
- * cur_pos = '\n';
- modified = TRUE;
- }
- else if (RET_opt == 'r') {
- cur_pos ++;
- ignore1char = TRUE;
- #ifndef msdos
- modified = TRUE;
- #endif
- }
- }
- } while (ignore1char == TRUE);
- if (cur_pos == last) break;
- if (buffer == fini && * cur_pos != '\n') {
- get_l_err2 = "Line too long - split";
- * buffer ++ = '\n';
- break;
- }
- } while ((* buffer ++ = * cur_pos ++) != '\n');
-
- current = cur_pos;
- if (read_chars <= 0) {
- if (buffer == begin)
- return ERRORS;
- if (* (buffer - 1) != '\n')
- if (loading == TRUE) /* Add '\n' to last line of file */
- * buffer ++ = '\n';
- else {
- * buffer = '\0';
- return NO_LINE;
- }
- }
-
- * buffer = '\0';
- return (int) (buffer - begin);
- }
-
- /*
- * Load_file loads the file with given name or the input pipe into memory.
- * If the file couldn't be opened, just an empty line is installed.
- * Buffer pointers are initialized.
- */
- void
- load_file_w_o_display (file)
- char * file;
- {
- register LINE * line = header;
- register int len;
- long nr_of_chars = 0L;
- int fd = -1; /* Filedescriptor for file */
-
- total_lines = 0; /* Zero lines to start with */
-
- overwriteOK = FALSE;
- /* Open file */
- writable = TRUE; /* Benefit of the doubt */
- if (file == NIL_PTR) {
- if (rpipe == FALSE)
- status_msg ("No file");
- else {
- fd = 0;
- file = "standard input";
- }
- file_name [0] = '\0';
- }
- else {
- copy_string (file_name, file); /* Save file name */
- if (access (file, 0 /* F_OK */) < 0) { /* Cannot access file */
- status_line ("New file ", file);
- overwriteOK = TRUE;
- }
- else if ((fd = open (file, O_RDWR | O_BINARY, 0)) >= 0) {
- overwriteOK = TRUE;
- writable = TRUE;
- }
- else if ((fd = open (file, O_RDONLY | O_BINARY, 0)) < 0)
- error ("Cannot open: " /*, file */, serror ());
- else { overwriteOK = TRUE;
- writable = FALSE;
- }
- }
-
- /* Read file */
- loading = TRUE; /* Loading file, so set flag */
- get_l_err1 = NIL_PTR;
- get_l_err2 = NIL_PTR;
-
- if (fd >= 0) {
- status_line ("Reading ", file);
- while (line != NIL_LINE
- && (len = get_line (fd, text_buffer)) != ERRORS) {
- line = line_insert (line, text_buffer, len);
- nr_of_chars += (long) len;
- }
- if (total_lines == 0 && line != NIL_LINE) /* The file was empty! */
- line = line_insert (line, "\n", 1);
- clear_buffer (); /* Clear output buffer: out_count = 0; */
- cur_line = header->next;
- (void) close (fd); /* Close file */
- if (line != NIL_LINE) {
- if (get_l_err1 != NIL_PTR || get_l_err2 != NIL_PTR) {
- ring_bell ();
- error (get_l_err1, get_l_err2);
- sleep (1);
- }
- fstatus ("Read", nr_of_chars);
- }
- }
- else /* Just install a "\n" */
- line = line_insert (line, "\n", 1);
-
- if (line == NIL_LINE) {
- sleep (2) /* give time to read allocation error msg */;
- viewonly = TRUE;
- }
-
- reset (header->next, 0); /* Initialize pointers */
- move_to (0, 0);
- loading = FALSE; /* Stop loading, reset flag */
- }
-
- void
- load_file (file)
- char * file;
- {
- load_file_w_o_display (file);
- /* Print screen */
- display (0, header->next, last_y, 0);
- move_to (0, 0);
- /* fstatus ("Read", -1L); */
- }
-
- /*-------------------------------------------------------------------------*/
-
- /*
- * Ask the user if he wants to save the file or not.
- */
- int
- ask_save ()
- {
- register uchar c;
-
- status_line (file_name [0] ? file_name : "[buffer]" ,
- " has been modified. Save? (y/n)");
- /* previously only basename (file_name) was printed */
- c = promptyn ();
- clear_status ();
- if (c == 'y')
- return wrt_text (TRUE);
- else if (c == 'n')
- return FINE;
- else {
- quit = FALSE; /* abort character has been given */
- return ERRORS;
- }
- }
-
- /*
- * Ask user if named file should be overwritten.
- */
- FLAG
- checkoverwrite (name)
- char * name;
- {
- uchar c;
-
- if (access (name, 0 /* F_OK */) < 0) /* Cannot access file */
- return TRUE; /* thus no danger of unwanted damage */
-
- status_line (name [0] ? name : "[buffer]" ,
- ": OK to overwrite? (y/n)");
- /* previously only basename (name) was printed */
- c = promptyn ();
- clear_status ();
- if (c == 'y')
- return TRUE;
- else if (c == 'n')
- return FALSE;
- else {
- /* quit = FALSE; abort character has been given */
- return FALSE;
- }
- }
-
- /*
- * Attach new file name to buffer
- */
- void
- NN ()
- {
- char file [maxLINE_LEN]; /* Buffer for new file name */
- if (get_file ("Enter new file name:", file) == ERRORS)
- return;
-
- overwriteOK = FALSE;
- writable = TRUE;
- modified = TRUE; /* cf. CHDI command */
- copy_string (file_name, file); /* Save new file name */
- clear_status ();
- }
-
- /*
- * Write file in core to disc.
- */
- /* Call graph for writing functions:
- panic --\
- > QUED --\
- ESC q --/ > ask_save --\
- ESC e ---> EDIT --/ \
- ESC v ---> VIEW -/ \
- ESC w -----------------------------> WT
- ESC z -----------> SUSP ----------/
- ESC ESC ---------> EXED ---------/
- */
- long write_count; /* number of chars written */
- void
- write_file (fd)
- int fd;
- {
- register LINE * line;
-
- write_count = 0L;
- clear_buffer (); /* out_count = 0; */
- for (line = header->next; line != tail; line = line->next) {
- if (line->shift_count & DUMMY) {
- if (line->next == tail && line->text [0] == '\n')
- continue;
- }
- if (writestring (fd, line->text) == ERRORS) {
- write_count = -1L;
- break;
- }
- write_count += (long) length_of (line->text);
- }
-
- if (write_count > 0L && flush_buffer (fd) == ERRORS)
- write_count = -1L;
-
- (void) close (fd);
- }
-
- int
- wrt_text (conditional)
- FLAG conditional;
- {
- char file [maxLINE_LEN]; /* Buffer for new file name */
- int fd; /* Filedescriptor of file */
- int ret;
-
- if (wpipe) {
- fd = STD_OUT;
- status_line ("Writing ", "to standard output");
- wpipe = FALSE; /* no further write to same stream possible */
- }
- else {
- if (modified == FALSE && viewonly == FALSE && conditional == TRUE) {
- status_msg ("Write not necessary.");
- return FINE;
- }
-
- /* Check if file_name is valid and if file can be written */
- if (file_name [0] == '\0' || writable == FALSE) {
- overwriteOK = FALSE;
- if ((ret = get_file ("Enter file name:", file)) != FINE)
- return ret;
- copy_string (file_name, file); /* Save file name */
- }
- if (overwriteOK == FALSE) {
- if (checkoverwrite (file_name) == TRUE)
- overwriteOK = TRUE;
- else { if (quit == FALSE)
- writable = FALSE;
- return ERRORS;
- }
- }
- if ((fd = creat (file_name, fprot)) < 0) { /* Empty file */
- error ("Cannot create or write: " /*, file_name */, serror ());
- writable = FALSE;
- return ERRORS;
- }
- else
- writable = TRUE;
-
- status_line ("Writing ", file_name);
- }
-
- write_file (fd);
-
- if (write_count == -1L)
- return ERRORS;
-
- modified = FALSE;
- rpipe = FALSE; /* File name is now assigned */
-
- /* Display how many chars (and lines) were written */
- /* fstatus ("Wrote", write_count); */
- fstatus ("Wrote", -1L);
- return FINE;
- }
-
- void
- WT ()
- {
- (void) wrt_text (TRUE);
- }
-
- void
- WTU ()
- {
- (void) wrt_text (FALSE);
- }
-
- int
- panicwrite ()
- {
- int fd;
- fd = creat (panic_file, fprot);
- write_file (fd);
- if (write_count == -1L)
- return ERRORS;
- else return FINE;
- }
-
- /*
- * Edit/view another file. If the current file has been modified,
- * ask whether the user wants to save it.
- * (We could allow to switch between edit and view mode without changing
- * the file, but we would have to consider carefully the relationship
- * between viewonly and modified.)
- */
- void
- edit_file (prompt, vomode)
- char * prompt;
- FLAG vomode;
- {
- char new_file [maxLINE_LEN]; /* Buffer to hold new file name */
-
- if (modified == TRUE && viewonly == FALSE && ask_save () != FINE)
- return;
-
- viewonly = vomode;
-
- /* Get new file name */
- if (get_file (prompt, new_file) == ERRORS)
- return;
-
- /* Free old linked list, initialize global variables and load new file */
- initialize ();
- clear_screen ();
- load_file (new_file [0] == '\0' ? NIL_PTR : new_file);
- }
-
- void
- EDIT ()
- {
- edit_file ("Edit file:", FALSE);
- }
-
- void
- VIEW ()
- {
- edit_file ("View file:", TRUE);
- }
-
- void
- edit_nth_file (n)
- int n;
- {
- int number, index;
-
- if (modified == TRUE && viewonly == FALSE && ask_save () != FINE)
- return;
-
- if (n == -1) {
- index = get_number ("Edit which file (enter number) ...", '\0', & number);
- if (index == ERRORS) return;
- n = number - 1 + fnami_min;
- }
- if (n < fnami_min) n = fnami_min;
- if (n > fnami_max) n = fnami_max;
-
- /* Free old linked list, initialize global variables and load new file */
- initialize ();
- clear_screen ();
-
- fnami = n;
- if (fnami < fnami_min) load_file (NIL_PTR);
- /* else load_file ((* fnamv) [fnami]); */
- else load_file (fnamv [fnami]);
- }
-
- void
- NXTFILE ()
- {
- if (hop_flag > 0) edit_nth_file (fnami_max);
- else edit_nth_file (fnami + 1);
- }
-
- void
- PRVFILE ()
- {
- if (hop_flag > 0) edit_nth_file (fnami_min);
- else edit_nth_file (fnami - 1);
- }
-
- void
- NTHFILE ()
- {
- edit_nth_file (-1);
- }
-
- /*
- * Leave editor. If the file has changed, ask if the user wants to save it.
- */
- void
- QUED ()
- {
- if (modified == TRUE && viewonly == FALSE && ask_save () != FINE)
- return;
-
- delete_yank_file ();
- set_cursor (0, YMAX);
- putchar ('\n');
- raw_mode (OFF);
- exit (0);
- }
-
- /*
- * Exit editing current file. If the file has changed, save it.
- * Edit next file if there is one.
- */
- void
- EXFILE ()
- {
- if (modified == TRUE)
- if (wrt_text (TRUE) != FINE) return;
-
- if (fnami < fnami_max) NXTFILE ();
- else {
- delete_yank_file ();
- set_cursor (0, YMAX);
- putchar ('\n');
- raw_mode (OFF);
- exit (0);
- }
- }
-
- /*
- * Exit editor. If the file has changed, save it.
- */
- void
- EXMINED ()
- {
- if (modified == TRUE)
- if (wrt_text (TRUE) != FINE) return;
-
- delete_yank_file ();
- set_cursor (0, YMAX);
- putchar ('\n');
- raw_mode (OFF);
- exit (0);
- }
-
- /*
- * Exit editing current file. Exit editor if multiexit flag set.
- */
- void
- EXED ()
- {
- if (multiexit == TRUE) EXFILE ();
- else EXMINED ();
- }
-
- /*
- * Count_chars () count the number of chars that the line would occupy on the
- * screen. Counting starts at the real x-coordinate of the line.
- * Was only called by delete_text ().
- */
- #ifdef UNUSED
- int
- count_chars (line)
- LINE * line;
- {
- register int cnt = get_shift (line->shift_count) * - SHIFT_SIZE;
- register char * textp = line->text;
-
- /* Find begin of line on screen */
- while (cnt < 0) {
- if (is_tab (* textp ++))
- cnt = tab (cnt);
- else
- cnt ++;
- }
-
- /* Count number of chars left */
- cnt = 0;
- while (* textp != '\n') {
- if (is_tab (* textp ++))
- cnt = tab (cnt);
- else
- cnt ++;
- }
- return cnt;
- }
- #endif /* UNUSED */
-
- /* ================================================================== *
- * Line wrap around *
- * ================================================================== */
-
- /*
- * Advance pointer and counter to next character.
- * Handle tab characters and Chinese 2-byte characters correctly.
- */
- void
- advance_char (poipoi, colpoi)
- char * * poipoi;
- int * colpoi;
- {
- if (is_tab (* * poipoi)) {
- (* poipoi) ++;
- * colpoi = tab (* colpoi);
- }
- else if (Chinese == TRUE && multichar (* * poipoi)) {
- (* poipoi) ++;
- (* poipoi) ++;
- (* colpoi) ++;
- (* colpoi) ++;
- }
- else {
- (* poipoi) ++;
- (* colpoi) ++;
- }
- }
-
- /*
- * JUS justifies the current line according to the current margins
- */
- void
- JUS ()
- {
- char * poi;
- char * last_blank;
- int column;
-
- poi = cur_line->text;
- column = 0;
- while (column < left_margin && (poi < cur_text || white_space (* poi))) {
- advance_char (& poi, & column);
- }
- if (column < left_margin) {
- move_address (poi, y);
- while (column < left_margin) {
- if (tab (column) <= left_margin) {
- S ('\t');
- column = tab (column);
- } else {
- S (' ');
- column ++;
- }
- }
- poi = cur_line->text; /* old text pointer may be invalid */
- column = 0; /* so start again */
- }
- last_blank = NIL_PTR;
- while (column < right_margin && * poi != '\n') {
- if (column >= left_margin &&
- (white_space (* poi) || * poi == '-')) last_blank = poi;
- advance_char (& poi, & column);
- }
- if (* poi != '\n') {
- if (last_blank != NIL_PTR) {
- poi = last_blank;
- poi ++;
- move_address (poi, y);
- SNL ();
- JUS ();
- }
- else { /* no wrapping point found */
- while (! white_space (* poi) && * poi != '\n')
- advance_char (& poi, & column); /* to handle Chin. */
- if (* poi == '\n') {
- move_address (poi, y);
- MRT ();
- }
- else {
- poi ++;
- move_address (poi, y);
- if (* poi != '\n') SNL ();
- else MRT ();
- JUS ();
- }
- }
- }
- else if (poi - last_blank == 1) {
- move_address (poi, y);
- DCC ();
- while (white_space (* cur_text)) DCC ();
- if (* cur_text != '\n') JUS ();
- else {
- poi = cur_text;
- poi --;
- if (Chinese == TRUE && inmultichar (cur_line->text, poi))
- poi --;
- while (white_space (* poi)) {
- DPC ();
- poi = cur_text;
- poi --;
- if (Chinese == TRUE && inmultichar (cur_line->text, poi))
- poi --;
- }
- MRT ();
- }
- }
- else {
- move_address (poi, y);
- MRT ();
- }
- }
-
- void
- modify_int (name, var, min, max)
- char * name;
- int * var;
- int min, max;
- {
- int number;
-
- build_string (text_buffer, "%s (%d), new value (Enter for current column):", name, * var);
- if (get_number (text_buffer, '0', & number) == ERRORS) return;
- if (number == 0) number = x + 1;
- if (number < min) {
- error ("Value too small", NIL_PTR);
- return;
- }
- if (number > max) {
- error ("Value too large", NIL_PTR);
- return;
- }
- * var = number;
- }
-
- void
- ADJLM ()
- { left_margin ++;
- modify_int ("left margin", & left_margin, 1, right_margin - 2);
- left_margin --;
- }
-
- void
- ADJRM ()
- { right_margin --;
- modify_int ("right margin", & right_margin, left_margin + 2, 1000);
- right_margin ++;
- }
-
- /* ================================================================== *
- * Miscellaneous *
- * ================================================================== */
-
- /*
- * Redraw the screen
- */
- void
- RD ()
- {
- reverse_off ();
- clear_screen ();
-
- /* display page */
- display (0, top_line, last_y, y);
-
- /* clear/redraw last line */
- set_cursor (0, YMAX);
- clear_lastline ();
- move_y (y);
- if (stat_visible == TRUE) rd_bottom_line ();
- }
-
- void
- RD_y (y_pos)
- int y_pos;
- {
- reverse_off ();
- clear_screen ();
-
- /* display page */
- display (0, top_line, last_y, y_pos);
-
- /* clear/redraw last line */
- set_cursor (0, YMAX);
- clear_lastline ();
- if (stat_visible == TRUE) rd_bottom_line ();
- }
-
- /*
- * Adjust current window size after WINCH signal
- */
- void
- RDwin ()
- {
- register LINE * current_line;
-
- winchg = FALSE;
- getwinsize ();
-
- current_line = cur_line;
- reset (top_line, y);
- /* move_y (find_y_w_o_RD (current_line)); */
- move_address (cur_text, find_y_w_o_RD (current_line));
- RD ();
- flush ();
- }
-
- void
- change_screen_size (sb, keep_columns)
- FLAG sb, keep_columns;
- {
- int index, mode1, mode2;
-
- /* Experimental area: */
- /* set_screen_mode (mode1); any available mode number */
- /* set_video_lines (mode1); 0/1/2: 200/350/400 lines */
- /* does not seem to have any effect */
- /* set_textmode_height (mode1); 0/1/2: font height 8/14/16 */
- /* set_grafmode_height (mode1, mode2);
- 0/1/2: font height 8/14/16 1/2/3/n: 14/25/43/n lines */
- /* set_fontbank (f); 0..7 */
- /**/
- if (hop_flag > 0) {
- #ifdef msdos
- if (keep_columns == TRUE) {
- if (sb == BIGGER) {
- index = get_number ("Switch to font bank (0..7) ", '\0', & mode1);
- if (index == ERRORS) return;
- set_fontbank (mode1);
- } else {
- index = get_number ("Set character height (<= 32 pixels) ", '\0', & mode1);
- if (index == ERRORS) return;
- set_font_height (mode1);
- }
- } else {
- if (sb == BIGGER) {
- #endif
- index = get_number ("Select video mode ", '\0', & mode1);
- if (index == ERRORS) return;
- set_screen_mode (mode1);
- #ifdef msdos
- } else {
- index = get_number ("Select graf font (0/1/2: font height 8/14/16) ", '\0', & mode1);
- if (index == ERRORS) return;
- index = get_number ("Select line number (1/2/3/n: 14/25/43/n) ", '\0', & mode2);
- if (index == ERRORS) return;
- set_grafmode_height (mode1, mode2); /* 0/1/2: font height 8/14/16 */
- /* 1/2/3/n: 14/25/43/n lines */
- }
- }
- #endif
- } else
- {
- resize_screen (sb, keep_columns);
- }
- RDwin ();
- }
-
- void
- LNCI ()
- {
- switch_textmode_height (TRUE);
- RDwin ();
- }
-
- void
- LNSW ()
- {
- switch_textmode_height (FALSE);
- RDwin ();
- }
-
- /*
- * Ignore this keystroke.
- */
- void
- I ()
- {
- }
-
- /*
- * Fortifying 'HOP' key.
- */
- void
- HOP ()
- {
- hop_flag = 2;
- if (! char_ready_within (500))
- status_msg ("Continue HOP command (next command fortified) ...");
- }
-
- /*
- * Cancel prefix function.
- */
- void
- CANCEL ()
- {
- hop_flag = 0;
- clear_status ();
- }
-
- /*
- * Call proc associated with function key.
- */
- void
- FUNKEY ()
- {
- (* keyproc) ('\0');
- keyproc = I;
- }
-
- /*
- * Toggle insert/overwrite mode.
- */
- void
- TOGINS ()
- {
- if (insert_mode == TRUE) insert_mode = FALSE;
- else insert_mode = TRUE;
- }
-
- #define cmd_char(c) (c < '\040' ? c + '\100' : (c >= '\140' ? c - '\040' : c))
-
- /*
- * Interpret control-Q commands. Most can be implemented with the Hop function.
- */
- void
- ctrlQ ()
- {
- uchar c;
- void (* func) ();
-
- if (! char_ready_within (500))
- status_msg ("^Q: Save Done eXit Quit Read Log / block: B/K mark Cop Ydel moV Wr...");
- if (quit == TRUE) return;
- c = readchar ();
- if (quit == TRUE) return;
- clear_status ();
- if ('0' <= c && c <= '9') {GOMAn (c); return;}
- if (c == '\033' || c == QUITCHAR) {CANCEL (); return;}
- switch (cmd_char (c)) {
- case 'B' : {GOMA () ; return;}
- case 'K' : { ; return;} /* not exactly WS function */
- case 'P' : { ; return;} /* not exactly WS function */
- case 'V' : { ; return;} /* not exactly WS function */
- case 'W' : /* not exactly WS function */
- case 'Z' : /* not exactly WS function */
- case 'Y' :
- case '\177' : {
- func = key_map [c];
- hop_flag = 1;
- (* func) (c);
- return;
- }
- case 'F' : {if (hop_flag > 0)
- SRV ();
- else
- SFW ();
- return;
- }
- case 'A' : {if (hop_flag > 0)
- REPL ();
- else
- GR ();
- return;
- }
- case 'Q' : {REPT (' '); return;} /* not exactly WS function */
- case 'L' : /* not exactly WS function */
- /*
- ^Q: B/K top/bottom block
- P last position
- W/Z continuous scroll
- V last find or block
- Y/DEL delete line right/left
- 0-9 marker
- F find
- A replace
- Q repeat next key/command
- L find misspelling
- */
- default : {
- func = key_map [c];
- if ((c < ' ') || ((voidfunc) func == (voidfunc) FUNKEY)) {
- /* (voidfunc) is an identity cast here. It seems to be required for
- the sake of the apparently totally rotten microvax C compiler */
- hop_flag = 1;
- (* func) (c);
- }
- else
- BAD (c);
- return;
- }
- }
- }
-
- /*
- * Interpret control-K commands.
- */
- void
- ctrlK ()
- {
- uchar c;
-
- if (! char_ready_within (500))
- status_msg ("^K: Save Done eXit Quit Read Log / block: B/K mark Cop Ydel moV Wr...");
- if (quit == TRUE) return;
- c = readchar ();
- if (quit == TRUE) return;
- clear_status ();
- if ('0' <= c && c <= '9') {MARKn (c); return;}
- if (c == '\033' || c == QUITCHAR) {CANCEL (); return;}
- switch (cmd_char (c)) {
- case 'S' : {WTU (); return;}
- case 'D' : {EXFILE (); return;}
- case 'X' : {EXMINED (); return;}
- case 'Q' : {QUED (); return;}
- case 'B' : {MARK () ; return;}
- case 'K' : {YA () ; return;} /* not exactly WS function */
- case 'H' : { ; return;} /* not exactly WS function */
- case 'C' : {PT () ; return;} /* not exactly WS function */
- case 'Y' : {DT () ; return;} /* not exactly WS function */
- case 'V' : {PT (); return;} /* not exactly WS function */
- case 'W' : {WB (); return;} /* not exactly WS function */
- case 'N' : { ; return;} /* not exactly WS function */
- case 'R' : {INSFILE (); return;}
- case 'L' : {CHDI (); return;}
- /*
- ^K 0-9 set/hide marker
- B/K block begin/end
- H block hide
- C/Y/V/W block copy/delete/move/write
- N column block
- */
- default : {
- BAD (c);
- return;
- }
- }
- }
-
- /*
- * Interpret control-O commands.
- */
- void
- ctrlO ()
- {
- uchar c;
-
- if (! char_ready_within (500))
- status_msg ("^O: L/R left/right margins...");
- if (quit == TRUE) return;
- c = readchar ();
- if (quit == TRUE) return;
- clear_status ();
- if ('0' <= c && c <= '9') {return;}
- if (c == '\033' || c == QUITCHAR) {CANCEL (); return;}
- switch (cmd_char (c)) {
- case 'L' : {ADJLM (); return;}
- case 'R' : {ADJRM (); return;}
- /*
- ^O L/R/M set left/right margin /release
- I/N set/clear tab
- G paragraph tab
- F ruler from line
- C center line
- S set line spacing
- W toggle word wrap
- T toggle ruler line
- J toggle justify
- V vari-tabs
- H hyph-help
- E soft hyph
- D print display
- P page break
- */
- default : {
- BAD (c);
- return;
- }
- }
- }
-
- /*
- * Interpret Escape commands.
- */
- void
- ESCAPE ()
- {
- uchar c;
- void (* func) ();
-
- if (! char_ready_within (500))
- status_msg ("ESC(exit) q(uit w(rite e(dit /\\(search) r(eplace d(irectory h(elp ...");
- if (quit == TRUE) return;
- c = readchar ();
- if (quit == TRUE) return;
- clear_status ();
- if ('0' <= c && c <= '9') {REPT (c); return;}
- switch (c) {
- case '\033' : {EXED (); return;}
- case 'q' : {QUED (); return;}
- case '/' : {SFW (); return;}
- case '\\' : {SRV (); return;}
- case 's' : {GR (); return;}
- case 'R' : {LR (); return;}
- case 'r' : {REPL (); return;}
- case 'w' : {WT (); return;}
- case 'W' : {WTU (); return;}
- case 'e' : {EDIT (); return;}
- case 'v' : {VIEW (); return;}
- case 'g' : {GOTO (); return;}
- case 'h' : {HELP (); return;}
- case '?' : {FS (); return;}
- case '.' : {RDwin (); return;}
- case 'i' : {INSFILE (); return;}
- case 'b' : {WB (); return;}
- case '=' : {REPT (' '); return;}
- case 'z' : {SUSP (); return;}
- case 'd' : {CHDI (); return;}
- case '!' : {SH (); return;}
- case ']' : {GOMA (); return;}
- case 'n' : {NN (); return;}
- case 'p' : {PBUF (); return;}
- case 'c' : {CMD (); return;}
- case ' ' : return;
- case 'X' : {changetocode (16); return;}
- case 'O' : {changetocode (8); return;}
- case 'D' : {changetocode (10); return;}
- case '+' : {NXTFILE (); return;}
- case '-' : {PRVFILE (); return;}
- case '#' : {NTHFILE (); return;}
- #ifdef msdos
- case 'm' : {change_screen_size (SMALLER, FALSE); return;}
- case 'M' : {change_screen_size (BIGGER, FALSE); return;}
- case 'l' : {change_screen_size (SMALLER, TRUE); return;}
- case 'L' : {change_screen_size (BIGGER, TRUE); return;}
- #endif
- case 'j' : {JUS (); return;}
- case '<' : {ADJLM (); return;}
- case '>' : {ADJRM (); return;}
- case QUITCHAR : {CANCEL (); return;}
- default : {
- func = key_map [c];
- if ((c < ' ') || ((voidfunc) func == (voidfunc) FUNKEY)) {
- /* (voidfunc) is an identity cast here. It seems to be required for
- the sake of the apparently totally rotten microvax C compiler */
- hop_flag = 1;
- (* func) (c);
- }
- else
- BAD (c);
- return;
- }
- }
- }
-
- /*
- * DIRECT () reads in a direct cursor movement input sequence and moves.
- */
- void
- DIRECT ()
- {
- uchar c;
- int xpos, ypos;
-
- c = get_digits (& ypos); /* c should be ';' */
- c = get_digits (& xpos);
- ypos = ypos - 1;
- xpos = xpos - 1;
- if (ypos > last_y) ypos = last_y;
- move_to (xpos, ypos);
- if (c == 'm') MARK (); /* middle mouse button */
- if (c == 'r') YA (); /* right mouse button */
- }
-
- /*
- * REPT () prompts for a count and wants a command after that. It repeats the
- * command count times. If a ^\ is given during repeating, stop looping and
- * return to main loop.
- */
- void
- REPT (firstdigit)
- char firstdigit;
- {
- register int count;
- register void (* func) ();
- int index, number;
-
- hop_flag = 0;
- if (firstdigit >= '0' && firstdigit <= '9')
- index = get_number ("Please continue repeat count...", firstdigit, & number);
- else
- index = get_number ("Please enter repeat count...", '\0', & number);
- if (index == ERRORS) return;
-
- func = key_map [index];
- if ((voidfunc) func == (voidfunc) I) { /* Function assigned? */
- /* (voidfunc) is an identity cast here. It seems to be required for
- the sake of the apparently totally rotten microvax C compiler */
- clear_status ();
- return;
- }
- if ((voidfunc) func == (voidfunc) FUNKEY) {
- /* (voidfunc) is an identity cast here. It seems to be required for
- the sake of the apparently totally rotten microvax C compiler */
- func = * keyproc;
- keyproc = I;
- index = '\0';
- }
-
- count = number;
- while (count -- > 0 && quit == FALSE) {
- if (stat_visible == TRUE)
- clear_status ();
- (* func) (index);
- flush ();
- }
-
- if (quit == TRUE) /* Abort has been given */
- error ("Repeat aborted", NIL_PTR);
- else
- clear_status ();
- }
-
- /*
- * Complains to illegal commands and eats up illegal escape sequences.
- */
- void
- BAD (c)
- uchar c;
- {
- static char message2 [] = "'**' - type a blank";
-
- if (c < ' ') { message2 [1] = '^'; message2 [2] = c + '@'; }
- else { message2 [1] = ' '; message2 [2] = c; }
- error ("Unknown command ", message2);
- while (readchar () != ' ' && quit == FALSE) {
- ring_bell ();
- flush ();
- }
- clear_status ();
- }
-
- /*
- * Change working directory.
- */
- void
- CHDI ()
- {
- char new_dir [maxLINE_LEN]; /* Buffer to hold new dir. name */
-
- #ifdef pc
- build_string (text_buffer, "Drive/Directory: %s, change to:", unnull (getcwd (new_dir, maxLINE_LEN)));
- #else
- build_string (text_buffer, "Directory: %s, change to:", unnull (getcwd (new_dir, maxLINE_LEN)));
- #endif
-
- if (get_file (text_buffer, new_dir) != FINE)
- return;
- #ifdef msdos
- if (new_dir [0] != '\0' && new_dir [1] == ':')
- if (new_dir [2] == '\0') {
- new_dir [2] = '.'; /* change to current dir. of drive */
- new_dir [3] = '\0';
- }
- #endif
- if (chdir (new_dir) == 0) {
- #ifdef msdos
- if (new_dir [0] != '\0' && new_dir [1] == ':')
- setdisk (((int) new_dir [0] & (int) '\137') - (int) 'A');
- RD (); /* disk error dialog may be on screen after chdir */
- #endif
- clear_status ();
- overwriteOK = FALSE; /* Same file base name ... */
- writable = TRUE;
- /* if (viewmode == FALSE) */
- modified = TRUE; /* would mean different file now */
- }
- else {
- #ifdef msdos
- RD (); /* disk error dialog may be on screen */
- #endif
- error ("Could not change work dir: ", serror ());
- }
- }
-
- /*
- * Print file status.
- */
- void
- FS1 ()
- {
- fstatus (file_name [0] ? "" : "[buffer]", -1L);
- }
- void
- FS ()
- {
- if (hop_flag > 0) if (fstat_always == FALSE) fstat_always = TRUE;
- else fstat_always = FALSE;
- else FS1 ();
- }
-
- /*
- * Show Help information on screen
- */
- void
- HELP ()
- {
- if (getenv ("MINEDHELP"))
- build_string (text_buffer, (char *) getenv ("MINEDHELP"), mined_dir);
- else build_string (text_buffer, helpcommand, mined_dir);
- clear_screen ();
- status_msg ("Wait for help...");
- flush ();
- raw_mode (OFF);
- system (text_buffer);
- sleep (1);
- raw_mode (ON);
- #ifdef pc
- status_msg ("help finished, press a key...");
- flush ();
- (void) readchar ();
- #endif
- clear_status ();
- RDwin ();
- }
-
- /*
- * Print buffer
- */
- void
- PBUF ()
- {
- int fd;
- char cmd [maxLINE_LEN]; /* Buffer for print command */
-
- if ((fd = scratch_file (READ, FALSE)) == ERRORS) {
- error ("Buffer is empty.", NIL_PTR);
- return;
- }
- close (fd);
- build_string (cmd, getenv ("MINEDPRINT") ?
- (char *) getenv ("MINEDPRINT") : printcommand, yank_file);
- /* Turbo-C wants the cast here since getenv must be declared as far * */
- clear_status ();
- set_cursor (0, YMAX);
- flush ();
- system (cmd);
- sleep (1);
- RDwin ();
- }
-
- /*
- * Pipe buffer
- */
- void
- CMD ()
- {
- int fd;
- char cmd [maxLINE_LEN]; /* Buffer for command */
- char command [maxLINE_LEN]; /* Buffer for full command */
-
- if ((fd = scratch_file (READ, FALSE)) == ERRORS) {
- error ("Buffer is empty.", NIL_PTR);
- return;
- }
- close (fd);
- if (get_string ("Command with buffer as input:", cmd, TRUE) != FINE)
- return;
- build_string (command, "%s < %s", cmd, yank_file);
- clear_status ();
- set_cursor (0, YMAX);
- flush ();
- raw_mode (OFF);
- system (command);
- sleep (1);
- raw_mode (ON);
- RDwin ();
- }
-
- /*
- * Called if an operation is not implemented
- */
- void
- notimpl ()
- {
- error ("Command not implemented", NIL_PTR);
- }
-
- /*
- * Suspend editor after writing back the file.
- */
- void
- SUSP ()
- {
- if (cansuspendmyself == TRUE) {
- if (hop_flag == 0 && modified == TRUE)
- if (wrt_text (TRUE) == ERRORS) return;
- set_cursor (0, YMAX);
- raw_mode (OFF);
- suspendmyself ();
- raw_mode (ON);
- clear_status ();
- RDwin ();
- }
- else notimpl ();
- }
-
- /*
- * Call an interactive shell.
- */
- void
- SH ()
- {
- #ifdef unix
- register int w;
- int pid, status, waiterr;
-
- switch (pid = vfork ()) {
- case -1: /* Error */
- error ("Cannot fork: ", serror ());
- return;
- case 0: /* This is the child */
- set_cursor (0, YMAX);
- putchar ('\n');
- raw_mode (OFF);
- if (rpipe) { /* Fix stdin */
- close (STD_IN);
- if (open ("/dev/tty", O_RDONLY, 0) < 0)
- exit (126);
- }
- execl (getenv ("SHELL"), getenv ("SHELL"), 0);
- _exit (127); /* Exit with 127 */
- default: /* This is the parent */
- do {
- w = wait (& status);
- } while (w != -1 && w != pid);
- waiterr = geterrno ();
- }
-
- raw_mode (ON);
- RDwin ();
-
- if (w == -1) {
- error ("Wait error: ", serrorof (waiterr));
- if (((status >> 8) == 127) || ((status >> 8) == 126)) sleep (2);
- }
- if ((status >> 8) == 127) /* Child died with 127 */
- error (getenv ("SHELL"), ": cannot exec this ${SHELL} (not found / not enough memory ?)");
- else if ((status >> 8) == 126)
- error ("Cannot open /dev/tty as fd #0", NIL_PTR);
- #else
- # ifdef msdos
- char old_dir [maxLINE_LEN]; /* Buffer to hold dir. name */
-
- (void) getcwd (old_dir, maxLINE_LEN);
-
- set_cursor (0, YMAX);
- raw_mode (OFF);
- system ("COMMAND.COM");
- raw_mode (ON);
- clear_status ();
- RDwin ();
-
- if (chdir (old_dir) == 0) {
- if (old_dir [0] != '\0' && old_dir [1] == ':')
- setdisk (((int) old_dir [0] & (int) '\137') - (int) 'A');
- RD (); /* disk error dialog may be on screen after chdir */
- } else {
- overwriteOK = FALSE; /* Same file base name ... */
- writable = TRUE;
- /* if (viewmode == FALSE) */
- modified = TRUE; /* would mean different file now */
- RD (); /* disk error dialog may be on screen */
- error ("Could not reset previous work dir: ", serror ());
- }
-
- # else
- # ifdef vms
- /* Who can tell me why this hangs the process after return from the CLI ?
- set_cursor (0, YMAX);
- raw_mode (OFF);
- system ("SPAWN");
- raw_mode (ON);
- clear_status ();
- RDwin ();
- */
- notimpl ();
- # else
- notimpl ();
- # endif
- # endif
- #endif
- }
-
- /* ================================================================== *
- * Main *
- * ================================================================== */
-
- char * minedopt;
-
- void
- WordStar_keys ()
- {
- int i;
-
- for (i = 0; i < 32; i ++) key_map [i] = ws_key_map [i];
- control_prefix = '\020';
- }
-
- FLAG
- eval_option ()
- {
- switch (* minedopt) {
- case 'v': viewonly = TRUE; break;
- case 'm': multiexit = TRUE; break;
- case 'p': proportional = TRUE; break;
- case 'r': RET_opt = 'r'; break;
- case 'R': RET_opt = 'R'; break;
- case 'C': Chinese = TRUE; break;
- case 'B': key_map ['\010'] = DPC;
- key_map ['\177'] = DCC;
- break;
- case 'W': WordStar_keys (); break;
- case 's': page_stay = TRUE; break;
- case 'S': page_scroll = TRUE; break;
- case 't': minedopt ++;
- if (* minedopt == '\0') {minedopt --; TABchar = TABdefault;}
- else TABchar = * minedopt;
- break;
- case 'd': minedopt ++;
- if (* minedopt == '-') display_delay = -1;
- else if (* minedopt >= '0' && * minedopt <= '9')
- display_delay = (int) * minedopt - (int) '0';
- else minedopt --;
- break;
- default: return FALSE;
- }
- return TRUE;
- }
-
- int
- main (argc, argv)
- int argc;
- char * argv [];
- {
- register int index; /* index in key table */
- int initlinenum;
- int initlini = 0;
- LINE * initline;
- char * Mark;
- FLAG goon;
-
- /* fprot = umask (0); */
-
- build_string (mined_dir, argv [0]);
- index = 0;
- while (mined_dir [index] != '\0') index ++;
- while (index >= 0 && mined_dir [index] != '/'
- #ifdef msdos
- && mined_dir [index] != '\\' && mined_dir [index] != ':'
- #endif
- #ifdef vms
- && mined_dir [index] != ']' && mined_dir [index] != ':'
- #endif
- ) index --;
- index ++; mined_dir [index] = '\0';
-
- if (getenv ("NoCtrlSQ") || getenv ("NoControlSQ")) {
- /* ^S and ^Q may come arbitrarily from terminal, so don't use them */
- controlQS = TRUE;
- key_map ['\021'] = I;
- key_map ['\023'] = I;
- }
- /* if (getenv ("MINEDMULT")) multiexit = TRUE; */
- if (getenv ("MINEDPROP")) proportional = TRUE;
- if (getenv ("MINEDCHIN")) Chinese = TRUE;
- if (getenv ("MINEDMAC")) RET_opt = 'R';
- if (getenv ("MINEDWS")) WordStar_keys ();
- Mark = (char *) getenv ("MINEDSHIFT");
- /* Turbo-C wants the cast here since getenv must be declared as far * */
- if (Mark != NIL_PTR) {
- SHIFT_MARK = Mark [0];
- if (Mark [0] != '\0') SHIFT_BEG = Mark [1];
- }
- Mark = (char *) getenv ("MINEDTAB");
- if (Mark != NIL_PTR) TABchar = (Mark [0] == '\0' ? TABdefault : Mark [0]);
- Mark = (char *) getenv ("MINEDRET");
- if (Mark != NIL_PTR) {
- RET_MARK = Mark [0];
- if (RET_MARK) RET_BLANK = Mark [1];
- if (RET_BLANK) RET_BLANK2 = Mark [2];
- }
-
- get_term ();
-
- if ((minedopt = (char *) getenv ("MINED")) != NIL_PTR)
- while (* minedopt != '\0') {
- (void) eval_option ();
- minedopt ++;
- }
-
- fnami = 1;
- goon = TRUE;
- do {
- if (fnami < argc) {
- if (* argv [fnami] == '+') {
- initlini = fnami;
- fnami += 1;
- }
- else if (* argv [fnami] == '-'
- #ifdef msdos
- || * argv [fnami] == '/'
- #endif
- ) {
- minedopt = argv [fnami];
- minedopt ++;
- goon = eval_option ();
- fnami += 1;
- }
- else goon = FALSE;
- } else goon = FALSE;
- } while (goon == TRUE);
-
- fnami_min = fnami;
- fnami_max = argc - 1;
- fnami_cnt = argc - fnami_min;
- fnamv = argv; /* Why did this produce a warning? C is such a stupid language! */
- if (! (fnami < argc))
- fnami = 0;
-
- if (! isatty (STD_IN)) { /* Reading from pipe */
- if (fnami != 0) {
- panic ("Cannot read both pipe and file", NIL_PTR);
- }
- rpipe = TRUE;
- modified = TRUE; /* Set modified flag not to loose buffer */
- #ifdef msdos
- panic ("Cannot edit after input from pipe", "MSDOS C incompatibility");
- #else
- if ((input_fd = open ("/dev/tty", O_RDONLY, 0)) < 0)
- panic ("Cannot open /dev/tty for read", serror ());
- #endif
- }
- if (! isatty (STD_OUT)) {
- wpipe = TRUE;
- modified = TRUE; /* Set modified flag not to ignore buffer on exit */
- /* if ((output_fd = open ("/dev/tty", O_WRONLY, 0)) < 0)
- panic ("Cannot open /dev/tty for write", serror ()); */
- }
-
- raw_mode (ON); /* Set tty to appropriate mode */
- clear_screen ();
-
- /*
- * Generate names of paste files and of panic-file
- */
- #ifdef unix
- temp_dir = getenv ("TMPDIR");
- if (temp_dir == NIL_PTR || temp_dir [0] == '\0') temp_dir = "/tmp";
- if (getenv ("USER")) {
- build_string (yankie_file, "%s/minedbuf.%s.", temp_dir, getenv ("USER"));
- build_string (panic_file, "%s/minedpanic.%s.%d", temp_dir, getenv ("USER"), getpid ());
- }
- else {
- build_string (yankie_file, "%s/minedbuf.%d.", temp_dir, geteuid ());
- build_string (panic_file, "%s/minedpanic.%d.%d", temp_dir, geteuid (), getpid ());
- }
- #endif
- #ifdef vms
- if (getenv ("SYS$SCRATCH"))
- temp_dir = "SYS$SCRATCH";
- else temp_dir = "SYS$LOGIN";
- if (getenv ("USER")) {
- build_string (yankie_file, "%s:$MINEDBUF$%s.", temp_dir, getenv ("USER"));
- build_string (panic_file, "%s:$MINEDPANIC$%s.%d", temp_dir, getenv ("USER"), getpid ());
- }
- else {
- build_string (yankie_file, "%s:$MINEDBUF$%d.", temp_dir, geteuid ());
- build_string (panic_file, "%s:$MINEDPANIC$%d.%d", temp_dir, geteuid (), getpid ());
- }
- #endif
- #ifdef msdos
- temp_dir = (char *) getenv ("TEMP");
- if (temp_dir == NIL_PTR || temp_dir [0] == '\0') temp_dir = (char *) getenv ("TMP");
- if (temp_dir == NIL_PTR || temp_dir [0] == '\0') temp_dir = "\\";
- build_string (yankie_file, "%s\\minedbuf.", temp_dir);
- build_string (panic_file, "%s\\mined-pa.nic", temp_dir);
- #endif
-
- header = tail = alloc_header (); /* Make header of list */
- if (header == NIL_LINE) panic ("Cannot allocate memory", NIL_PTR);
- header->text = NIL_PTR;
- header->next = tail->prev = header;
-
- /* Load the file (if any) */
- if (fnami == 0)
- load_file_w_o_display (NIL_PTR);
- else {
- /* This should be applied to all file names, or better, not at all:
- if (length_of (argv [fnami]) > maxLINE_LEN) {
- argv [fnami] [maxLINE_LEN] = '\0';
- }
- */
- load_file_w_o_display (argv [fnami]);
- }
- loading = TRUE; /* keep loading flag TRUE until entering main loop */
-
- if (initlini != 0) {
- make_number (& initlinenum, argv [initlini] + 1);
- if (initlinenum > 0) {
- if (initlinenum <= 0 || (initline = proceed (header->next, initlinenum - 1)) == tail)
- error ("Illegal line number: ", num_out ((long) initlinenum));
- else {
- move_to (x, find_y_w_o_RD (initline));
- fstatus ("Read", -1L);
- }
- }
- }
- if (wpipe) {
- file_name [0] = '\0'; /* don't let user believe he's editing a file */
- fstatus ("Editing for standard output", -1L);
- }
- RD ();
- flush ();
- catch_signals (catch_interrupt);
- loading = FALSE;
-
- /* Main loop of the editor */
- for (;;) {
- if (fstat_always == TRUE && stat_visible == FALSE) FS1 ();
- index = readchar ();
- if (stat_visible == TRUE)
- clear_status ();
- if (quit == FALSE) { /* Call the function for the typed key */
- (* key_map [index]) (index);
- if (hop_flag > 0) hop_flag --;
- flush (); /* Flush output (if any) */
- }
- if (quit == TRUE) {
- CANCEL ();
- quit = FALSE;
- }
- }
- /* NOTREACHED */
- }
-
- /* ================================================================== *
- * End *
- * ================================================================== */
-